#include <stdarg.h>
#include <stddef.h>
#include "lib/serial.h"
#include "lib/stdout.h"

static char digits_hex[] = "0123456789abcdef";

static void putc(char c) {
    // wait for Transmit Holding Empty to be set in LSR.
    while((io_readb(UART0_LSR) & LSR_TX_IDLE) == 0);
    io_writeb(UART0_DAT, c);
}

static void puts(char *str) {
    while (*str != 0) {
        putc(*str);
        str++;
    }
}

static void printint(int xx, int base, int sign) {
	char buf[16];
	unsigned int x;
	if (sign && (sign = xx < 0))
		x = -xx;
	else
		x = xx;

	int i = 0;
	do {
		buf[i++] = digits_hex[x % base];
	} while ((x /= base) != 0);

	if (sign)
		buf[i++] = '-';

	while (--i >= 0)
		putc(buf[i]);
}

static void printptr(unsigned long x) {
	int i;
	putc('0');
	putc('x');
	for (i = 0; i < (sizeof(unsigned long) * 2); i++, x <<= 4)
		putc(digits_hex[x >> (sizeof(unsigned long) * 8 - 4)]);
}

// 格式化输出，目前仅支持 
// 32位: %o (八进制), %d (十进制), %x (十六进制)
// 64位: %p (指针)
// 其他: %s (字符串), %c (字符)
void printk(char *fmt, ...) {
	va_list ap;
	int i, c;
	char *s;
	
	if (fmt == 0)
		return;
	
	va_start(ap, fmt);
	for (i = 0; (c = fmt[i] & 0xff) != 0; i++) {
		if (c != '%') {
			putc(c);
			continue;
		}
		c = fmt[++i] & 0xff;
		if (c == 0) {
			break;
		}
		switch (c) {
			case 'o':
				printint(va_arg(ap, int), 8, 1);
				break;
			case 'd':
				printint(va_arg(ap, int), 10, 1);
				break;
			case 'x':
				printint(va_arg(ap, int), 16, 1);
				break;
			case 'p':
				printptr(va_arg(ap, unsigned long));
				break;
			case 's':
				if ((s = va_arg(ap, char *)) == 0)
					s = "(null)";
				for (; *s; s++)
					putc(*s);
				break;
			case 'c':
				putc((char)va_arg(ap, int));
				break;
			case '%':
				putc('%');
				break;
			default:
			 	// Print unknown % sequence to draw attention.
			 	putc('%');
			 	putc(c);
			 	break;
		}
	}
}

// 显示系统 LOGO 和签名信息
void display_logo() {
	puts("\n\n\n ________     .---.          ,-----.          .-\'\'\'-.  \n"
		"|        |    | ,_|        .\'  .-,  \'.       / _     \\ \n"
		"|   .----\'  ,-./  )       / ,-.|  \\ _ \\     (`\' )/`--\' \n"
		"|  _|____   \\  \'_ \'`)    ;  \\  \'_ /  | :   (_ o _).    \n"
		"|_( )_   |   > (_)  )    |  _`,/ \\ _/  |    (_,_). \'.  \n"
		"(_ o._)__|  (  .  .-\'    : (  \'\\_/ \\   ;   .---.  \\  : \n"
		"|(_,_)       `-\'`-\'|___   \\ `\"/  \\  ) /    \\   `--\'  | \n"
		"|   |         |        \\   \'. \\_/``\".\'      \\       /  \n"
		"\'---\'         `--------`     \'-----\'         `-...-\'   \n\n");
	puts("Copyright (C) Sayaka-4987 (Yuxiao Wang) 2023.\n\n\n"); 
}